# -*- coding:utf-8 -*-
import selenium.common.exceptions
from selenium.webdriver.common import action_chains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec
from UICaseRunner.config import project_config
import pyzbar
from PIL import Image


class ElementOperate:
    def __init__(self, drivers=None):
        self.driver = drivers

        self.logger = project_config.logger

    # 不需要定位的浏览器直接操作
    '''
    浏览器回退
    '''
    def browser_back(self):
        self.driver.back()
        print("浏览器回退成功")

    '''
    浏览器前进
    '''
    def forward(self):
        self.driver.forward()
        print("浏览器前进成功")

    '''
    浏览器刷新
    '''
    def refresh(self):
        self.driver.refresh()
        print("浏览器刷新成功")

    '''
    浏览器获取当前页的链接
    '''
    def get_url(self):
        action_chains.time.sleep(1)
        current_url = self.driver.current_url
        return current_url

    '''
    操作浏览器的系统弹窗处理--接受
    '''
    def sys_alert(self):
        self.driver.switch_to.alert.accept()
        # self.driver.switch_to.window(a)

    '''
    切换到iframe
    '''
    def switch_to_iframe(self, step):
        self.driver.switch_to_frame(step["frame_name"])

    '''
    切换窗口
    '''
    @staticmethod
    def open_new_tab(operate):
        # if operate_class.get("find_type") == be.open_new_tab:
        #     js = operate_class["msg"]
        #     self.driver.execute_script(js)
        #     windows = self.driver.window_handles
        #     self.driver.switch_to.window(windows[-1])
        #     return {"result": True}
        print(operate)
        return {"result": True}

    '''
    元素区域截图
    '''
    def screenshot_as_png_element(self):
        png_file = self.driver.get_screenshot_as_png
        img = Image.open(png_file)
        barcodes = pyzbar.pyzbar.decode(img)
        for barcode in barcodes:
            url = barcode.data.decode("utf-8")
            print(url)
            return url

    '''
    元素区域截图
    '''
    def screenshot_element(self):
        action_chains.time.sleep(3)
        self.driver.get_screenshot_as_file('qrimg.png')
        action_chains.time.sleep(1)
        img = 'qrimg.png'
        img = Image.open(img)
        barcodes = pyzbar.pyzbar.decode(img)
        for barcode in barcodes:
            url = barcode.data.decode("utf-8")
            return url

    # 需要参数的浏览器操作
    '''
    鼠标悬停
    '''
    def move_to_element(self, step):
        """
        鼠标悬停在元素上
        :param step: 元素定位器
        """
        action_chains.ActionChains(self.driver).move_to_element(self.get_element(step)["locator"]).perform()

    '''
    点击事件
    '''
    def click(self, step):
        """
        对元素一次点击操作
        :param step: 元素定位器
        """
        if 'index' in step:
            web_element = self.get_elements(step)["locator"][step.get("index")]
        else:
            web_element = self.get_element(step)["locator"]
        web_element.click()

    '''
    获取文本
    '''
    def get_text(self, step):
        """
        获取元素中的文本信息
        :param step: 元素定位器
        """
        action_chains.time.sleep(1.5)
        element_info = self.get_element(step)["locator"]
        result = element_info.text
        # re_result = re.findall(r'[a-zA-Z\d+\u4e00-\u9fa5]', result)     # 只匹配中文，大小写，字母
        return result

    '''
    输入文本
    '''
    def send_keys(self, step):
        """
        在某个输入框类型的元素中输入文本
        :param step:
        :return:
        """
        value = step.get('msg')
        self.get_element(step)["locator"].clear()
        self.get_element(step)["locator"].send_keys(value)
        return True

    # 操作元素
    def operate_element(self, step):
        # get_element返回的参数是一个dict，有定位元素的信息和元素定位信息

        try:
            if step["operate_type"] == "send_keys":
                self.send_keys(step)
                self.logger.info("这个元素 %s 已经操作成功" % step["step_name"])
                print("这个元素 %s 已经操作成功" % step["step_name"])
            elif step["operate_type"] == "click":
                self.click(step)
                self.logger.info("这个元素 %s 已经操作成功" % step["step_name"])
                print("这个元素 %s 已经操作成功" % step["step_name"])
            elif step["operate_type"] == "get_value":
                self.get_text(step)
                self.logger.info("这个元素 %s 已经操作成功" % step["step_name"])
                print("这个元素 %s 已经操作成功" % step["step_name"])
            elif step["operate_type"] == "sleep":
                action_chains.time.sleep(step.get("time"))
                self.logger.info("这步操作就是sleep %s 秒" % step["time"])
            elif step["operate_type"] == "switch_frame":
                self.switch_to_iframe(step)
            elif step["operate_type"] == "switch_new_frame":
                self.switch_to_new_iframe(step)
            elif step["operate_type"] == "switch_to_new_tab":
                self.switch_to_new_tab()
        except Exception as e:
            self.logger.error("==元素 %s 操作失败" % step["step_name"])
            print("==元素 %s 操作失败" % step["step_name"])
            raise e

    # 获取元素位置信息
    def get_element(self, step):
        """
        # :param driver: driver session
        :param step: 操作步骤内容
        :return: 成功：是一个dict，元素是否定位和元素定位信息；失败：元素是否定位和遇到的异常
        """
        try:
            WebDriverWait(self.driver, 5).until(lambda x: x.find_element(by=step["find_type"],
                                                                         value=step["operate_elem"]))
            self.logger.info("==步骤 %s 已经定位到" % step["operate_elem"])
            loc = self.driver.find_element(by=step["find_type"], value=step["operate_elem"])
            return loc
            # return {"locator": self.driver.find_element(by=step["find_type"], value=step["operate_elem"])}
        except selenium.common.exceptions.NoSuchElementException as e:
            self.logger.error("没有这个元素", step["operate_elem"], e)
            raise e
        except selenium.common.exceptions.TimeoutException as e:
            self.logger.error("==查找元素超时== " + step["operate_elem"])
            raise e
        except selenium.common.exceptions.WebDriverException as e:
            self.logger.error("WebDriver出现问题了", e)
            raise e

    # 复杂定位多元素位置信息
    def get_elements(self, step):
        """
        多个元素定位
        :param step: 操作内容
        :return: 定位到的元素
        """
        try:
            WebDriverWait(self.driver, 5).until(lambda x: x.find_elements(by=step["find_type"],
                                                                          value=step["operate_elem"]))
            self.logger.info("==步骤 %s 已经定位到" % step["operate_elem"])
            return {"locator": self.driver.find_elements(by=step["find_type"], value=step["operate_elem"])}

        except selenium.common.exceptions.NoSuchElementException as e:
            self.logger.error("没有这个元素", step["operate_elem"], e)
            raise e
        except selenium.common.exceptions.TimeoutException as e:
            self.logger.error("==查找元素超时== " + step["operate_elem"])
            raise e
        except selenium.common.exceptions.WebDriverException as e:
            self.logger.error("WebDriver出现问题了", e)
            raise e

    # 单个元素定位
    def find_element(self, *loc):
        """
        单个元素定位
        :param loc: 传入元素属性
        :return: 定位到的元素
        """
        try:
            WebDriverWait(self.driver, 10).until(ec.visibility_of_element_located(loc))
            return self.driver.find_element(*loc)
        except Exception as e:
            print(e)
            self.logger.error("{0}页面中未能找到{1}元素".format(self, loc))

    # 鼠标hover到某个元素
    def hover_element(self, *loc):
        """
        单个元素定位
        :param loc: 传入元素属性
        :return: 定位到的元素
        """
        try:
            action_chains.ActionChains(self.driver).move_to_element(*loc).perform()  # 对该元素执行悬停操作
        except Exception as e:
            print(e)
        else:
            self.logger.error("{0}页面中未能找到{1}元素".format(self, loc))

    # 判断元素是否存在的方法
    def is_element_exist(self, *loc):
        try:
            self.driver.find_element(*loc)
            return True
        except Exception as e:
            print(e)
            return False

    # 切换到新窗口
    def switch_to_new_tab(self):
        self.driver.switch_to_window(self.driver.window_handles[-1])

    # 切换到第一个窗口
    def switch_to_previous_tab(self):
        self.driver.switch_to_window(self.driver.window_handles[0])

    '''
    切换到iframe,可以自定义路径，也可以直接用frame_name/id
    '''
    def switch_to_new_iframe(self, step):
        try:
            self.driver.switch_to_frame(step["locator"])
        except Exception as e:
            print(e)
        else:
            self.driver.switch_to_frame(self.get_element(step)["locator"])
